home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS11.ADF
/
C
/
ps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-08-05
|
7KB
|
219 lines
#include <stdio.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <exec/memory.h>
#include <exec/tasks.h>
/*
* P S : Like the UN*X command of the same name, this reports on
* running processes in the system. The current version only
* reports CLI processes, so you don't see the filesystem
* tasks. Written because I got tired of seeing the question
* marks that status spits out at every opportunity.
* This will build OK with 16 bit integers.
*
* Usage: ps [-f]
*
* Author: Dewi Williams ..!ihnp4!druca!dewi
* Status: Public domain.
*/
/* Defines */
/* Change typeless BCPL BPTR to typed C (for struct pointers). Don't
* use this define on an APTR, that's only a badly disguised void *.
*/
#define BPTR_TO_C(strtag, var) ((struct strtag *)(BADDR( (ULONG) var)))
/* Use AmigaDOS i/o to keep executable size down */
#define WSTR(s) (void)Write(OutLock, s, (long)strlen(s))
#define WCHR(s) (void)Write(OutLock, s, 1L) /* char w/ d. quotes */
#define TO_ASC(n) ((n) + '0') /* make it printable! */
/* Casting conveniences */
#define PROC(task) ((struct Process *)task)
#define ROOTNODE ((struct RootNode *)DOSBase->dl_Root)
#define CLI(proc) (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
/* Externs */
extern struct DosLibrary *DOSBase; /* dos library base pointer */
extern struct FileLock *Output(); /* get output file handle */
/* Globals */
static struct FileLock *OutLock; /* used by WSTR define */
static int fullopt = 0; /* set by -f command line flag */
main(argc, argv)
int argc;
char **argv;
{
register ULONG *tt; /* References TaskArray */
register int count; /* loop variable */
register UBYTE *port; /* msgport & ptr arith */
register struct Task *task; /* EXEC descriptor */
char strbuf[256]; /* scratch for btocstr() */
char *btocstr(); /* BCPL BSTR to ASCIIZ */
void disp_hdr(); /* display ps header */
void display(); /* display data for one process */
OutLock = Output(); /* initialize output handle */
if (argc > 1 && strcmp(argv[1], "-f") == 0) fullopt = 1;
tt = (unsigned long *)(BADDR(ROOTNODE->rn_TaskArray));
if (fullopt) disp_hdr();
Forbid(); /* need linked list consistency */
/* Loop through the data for the CLI processes. */
for (count = 1; count <= (int)tt[0] ; count++) {/* or just assume 20?*/
if (tt[count] == 0) continue; /* nobody home */
/* Start by pulling out MsgPort addresses from the TaskArray
* area. By making unwarranted assumptions about the layout
* of Process and Task structures, we can derive these
* descriptors. Every task has an associated process, since
* this loop drives off a CLI data area.
*/
port = (UBYTE *)tt[count];
task = (struct Task *)(port - sizeof(struct Task));
/* Sanity check just in case */
if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == NULL)
continue; /* or complain? */
/* Pass the C string version of the command name to
* the display routine.
*/
display(count, task->tc_Node.ln_Name,
btocstr(CLI(PROC(task))->cli_CommandName, strbuf),
task->tc_Node.ln_Pri);
}
Permit(); /* outside critical region */
exit(0);
}
/*
* Convert a BCPL string to a C string. To avoid scrogging in-memory
* stuff, it copies it first. Your data area better be big enough!
*/
char *
btocstr(b, buf)
ULONG b;
char *buf;
{
register char *s;
s = (char *)BADDR(b); /* Shift & get length-prefixed str */
(void)movmem(s +1, buf, s[0]); /* a.k.a memcpy */
buf[s[0]] = '\0';
return buf;
}
/*
* Display the header for the output.
*/
void
disp_hdr()
{
WSTR("Process # CLI Type Command Name Priority\n");
}
/*
* Display the information for a particular CLI process. Keep the format
* string in sync with that of disp_hdr().
*/
void
display(tnum, type, name, pri)
int tnum; /* CLI process number */
char *type; /* Initial, Background or New CLI */
char *name; /* Command name if CLI's running one */
int pri; /* priority of CLI & command */
{
char *psitoa();
char buf[80];
char *ext_len();
register char *p = buf;
if (*name == '\0') name = "<Cli>"; /* Null, nothing loaded */
if (fullopt) {
p = ext_len(psitoa(tnum, p), 11);
strcpy(p, type);
p = ext_len(p, 17);
strcpy(p, name);
p = ext_len(p, 21);
(void)psitoa(pri, p);
} else {
p = ext_len(psitoa(tnum, p), 2);
*p++ = ':';
*p++ = ' ';
strcpy(p, name);
}
WSTR(buf);
WCHR("\n");
}
/*
* Everything after here is a hack to avoid dragging in printf.
* ------------------------------------------------------------
*/
/*
* Limited itoa style function. Don't use it anywhere else! Used to keep
* things small & avoid printf. Has a very limited range (3 digits +/- sign).
* This hack avoids having to do the recursion & reverse of K&R itoa.
*/
char *
psitoa(num, into)
int num; /* number to convert */
char *into; /* write it into here */
{
register char *p = into;
if (num < 0) {
*p++ = '-';
num = -num;
}
if (num > 99) {
*p++ = TO_ASC(num/100);
*p++ = TO_ASC((num%100)/10);
*p++ = TO_ASC(num%10);
} else if (num > 9) {
*p++ = TO_ASC(num/10);
*p++ = TO_ASC(num%10);
} else
*p++ = TO_ASC(num);
*p = '\0'; /* end of the string */
return into;
}
/*
* Extend to length. Assumes strlen(s) never greater than len.
*/
char *
ext_len(s, len)
char *s; /* must be large enough for extension to len */
int len;
{
register int leftover;
register int slen = strlen(s);
register char *p = s + slen;
for(leftover = len - slen; leftover > 0; leftover--)
*p++ = ' ';
*p = '\0'; /* null terminate */
return p; /* return loc after string */
}